Kuromojiで日本語全文検索 – AWSで始めるElasticSearch(1)
はじめに
初めまして、ブロガーとして出張してきました@smokeymonkeyです。
今回、AWS上にElasticSearchを導入し、試行錯誤した結果をまとめてみました。シリーズものとして何度か続けていきたいと思いますので、どうぞ宜しくお願い致します。
ElasticSearchとは
Apache v2ライセンスで公開されているオープンソースソフトウェアであり、全文検索エンジンであるLuceneを使用した、全文検索システムです。特徴として
- RESTfulなAPIが使える
- InputもOutputもJSON
- スキーマフリーなので面倒な定義無しにデータを登録可能
等があります。
Kuromojiとは
Kuromojiはatilika社製のJavaで書かれた日本語形態素解析ソフトウェアで、Apache v2ライセンスで公開されているオープンソースソフトウェアです。形態素解析としてはChaSenやMeCabがメジャーで古くから使われていますが、Kuromojiは比較的新しいソフトウェアです。
Amazon LinuxへのElasticSearchのセットアップ
ElasticSearchの動作にはJavaが必要ですが、Amazon Linuxの場合初期導入されています。
$ java -version java version "1.6.0_24"<br />OpenJDK Runtime Environment (IcedTea6 1.11.13) (amazon-65.1.11.13.56.amzn1-x86_64) OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
ElasticSearchの公式サイトから最新バージョンをダウンロードします。ElasticSearchはzipファイル、tar.gzファイル、debパッケージファイル、rpmパッケージファイルにて配布されています。今回はrpmパッケージからインストールを行います。
$ wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.5.noarch.rpm $ sudo rpm -ivh ./elasticsearch-0.90.5.noarch.rpm Preparing... ################################# [100%] Updating / installing... 1:elasticsearch-0.90.5-1 ################################# [100%] Starting elasticsearch: [ OK ]
ElasticSearchの動作確認
それでは簡単な動作確認をしてみます。まずはPUTを使ってテストデータを登録します。
ここではIndexを「mytest」、Typeを「test」としました。
$ curl -XPUT http://localhost:9200/mytest/test/1 -d ' > { > "title" : "memo", > "text" : "hogehoge" > }' {"ok":true,"_index":"mytest","_type":"test","_id":"1","_version":1}
そしてGETを使って検索してみます。
$ curl -XGET http://localhost:9200/mytest/test/_search -d ' > { > "query": > { "match":{"title":"memo"}} > }' { "array": { "took": 85, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 0.30685282, "hits": [ { "_index": "mytest", "_type": "test", "_id": "1", "_score": 0.30685282, "_source": { "title": "memo", "text": "hogehoge" } } ] } } }
titleが「memo」であるデータが戻り値として返ってきました!
Kuromojiプラグインのセットアップ
ElasticSearchのpluginコマンドを使って、Kuromojiプラグインをインストールします。
$ sudo /usr/share/elasticsearch/bin/plugin --install elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 -> Installing elasticsearch/elasticsearch-analysis-kuromoji/1.5.0... Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-analysis-kuromoji/elasticsearch-analysis-kuromoji-1.5.0.zip... Downloading ....................................................DONE Installed elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 into /usr/share/elasticsearch/plugins/analysis-kuromoji
プラグインをインストールした後はElasticSearchの再起動が必要です。
$ sudo service elasticsearch restart Stopping elasticsearch: [ OK ] Starting elasticsearch: [ OK ]
Kuromojiプラグインの動作確認
それでは簡単な動作確認をしてみましょう。
kurotestというIndexで、kuromojiをアナライザと使うように設定します。
$ curl -XPUT 'http://localhost:9200/kurotest/' -d' > { > "index":{ > "analysis":{ > "tokenizer" : { > "kuromoji" : { > "type" : "kuromoji_tokenizer" > } > }, > "analyzer" : { > "analyzer" : { > "type" : "custom", > "tokenizer" : "kuromoji" > } > } > } > } > }' {"ok":true,"acknowledged":true}
このkurotestにPOSTで日本語文字列を投げると、分かち書きされて返ってきます!
$ curl -XPOST 'http://localhost:9200/kurotest/_analyze?analyzer=analyzer&petty' -d '梅酒は水' { "array": { "tokens": [ { "token": "梅酒", "start_offset": 0, "end_offset": 2, "type": "word", "position": 1 }, { "token": "は", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "水", "start_offset": 3, "end_offset": 4, "type": "word", "position": 3 } ] } }
ElasticSearchとKuromojiプラグインで日本語全文検索
お待たせしました!ここからが本番です。
まずはElasticSearchの設定ファイルを修正し、kuromojiをデフォルトアナライザとして設定します。設定後はElasticSearchの再起動が必要です。
$ sudo vi /etc/elasticsearch/elasticsearch.yml index.analysis.analyzer.default.type: custom index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer $ sudo service elasticsearch restart
それでは二つの日本語文字列をテストデータとして登録してみます。
$ curl -XPUT http://localhost:9200/jptest/test/1 -d ' > { > "title" : "メモ", > "text" : "梅酒は水" > }' {"ok":true,"_index":"jptest","_type":"test","_id":"1","_version":1} $ curl -XPUT http://localhost:9200/jptest/test/2 -d ' > { > "title" : "メモ2", > "text" : "麦酒は命" > }' {"ok":true,"_index":"jptest","_type":"test","_id":"2","_version":1}
まずは「梅酒」という文字列で検索してみます。
$ curl -XGET http://localhost:9200/jptest/test/_search -d ' > { > "query": > { "match":{"text":"梅酒"}} > }' { "array": { "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 0.15342641, "hits": [ { "_index": "jptest", "_type": "test", "_id": "1", "_score": 0.15342641, "_source": { "title": "メモ", "text": "梅酒は水" } } ] } } }
ちゃんと「梅酒は水」がヒットしました!
次に「梅酒は」という文字列で検索してみます。
$ curl -XGET http://localhost:9200/jptest/test/_search -d ' > { > "query":> { "match":{"text":"梅酒は"}} > }' { "array": { "took": 5, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 2, "max_score": 0.2169777, "hits": [ { "_index": "jptest", "_type": "test", "_id": "1", "_score": 0.2169777, "_source": { "title": "メモ", "text": "梅酒は水" } }, { "_index": "jptest", "_type": "test", "_id": "2", "_score": 0.02250402, "_source": { "title": "メモ2", "text": "麦酒は命" } } ] } } }
「梅酒は水」と「麦酒は命」の2つがヒットしました。ここで注目したいのは"_score"です。
「梅酒は水」は「梅酒は」のうち3文字がヒットするためスコアが高く(0.2169777)、「麦酒は命」は「酒は」の2文字のみがヒットするためスコアが低く(0.02250402)なっています。これで分かち書きによって日本語全文検索が行われていることがわかります。
まとめ
ElasticSearchはIn/OutがJSONであることからとても汎用性の高いツールだと思います。次回は可用性を高めるべくClusterの設定を行いたいと思います。